/*
   Windows客户端访问Linux服务器
*/
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <WinSock2.h>
#include <string>
#include <cstdlib>
#include <cstdio>

#pragma warning(disable:4996)
#pragma comment(lib, "ws2_32.lib") //连接库，Windows平台上用于支持网络编程的库

uint16_t serverport = 8081;
std::string serverip = "120.26.46.38";

int main()
{
    WSADATA WSAData;
    if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
    {
        std::cerr << "init error" << std::endl;
        return -1;
    }
    /*上面这段代码的作用是在程序启动时初始化Winsock库，以便程序可以使用网络功能。如果初始化失败，程序会输出错误信息并退出。*/
    int sock = socket(AF_INET, SOCK_DGRAM, 0); // AF_INET：ipv4地址族 SOCK_DGRAM：数据报字节流，用于UDP
    if (sock < 0)
    {
        std::cerr << "socket create error：" << strerror(errno) << std::endl;
        exit(-2);
    }
    // 2.绑定客户端的IP地址和端口号
    /*client这里要不要bind呢？要的！socket通信的本质[clientip:clientport，serverip:serverport]。
      要不要自己bind呢？不需要自己bind，也不要自己bind，OS自动给我们进行bind--
      为什么？client的port要随机让OS分配防止client出现启动冲突。
      (不同的软件进行不同的时间点服务器访问时，端口号不同，因为端口号存在被占用的情况)。*/

    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    // 发信息--需要知道服务器的IP地址和端口号port
    server.sin_family = AF_INET;
    server.sin_port = htons(serverport);
    server.sin_addr.s_addr = inet_addr(serverip.c_str());

    while (true)
    {
        // 1.发
        /*ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);*/
        // 获取信息
        //cout << "please Enter#";
        std::cerr << "please Enter#";
        std::string message;
        std::getline(std::cin, message); // 遇到空格继续读取
        sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr*)&server, sizeof(server));

        // 2.收
        char buffer[2048];
        struct sockaddr_in serverpeer;
        int serverlen = sizeof(serverpeer);
        int n = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&serverpeer, &serverlen);
        if (n > 0)
        {
            buffer[n] = 0;
            std::cout << buffer << std::endl;
        }
    }
    closesocket(sock);
    WSACleanup();
	return 0;
}